package com.demo.controller;

import com.demo.common.Result;
import com.demo.pojo.dto.ScheduleListDTO;
import com.demo.pojo.entity.Schedule;
import com.demo.service.ScheduleService;
import com.demo.service.IntelligentScheduleService;
import com.demo.pojo.dto.AdvancedScheduleRequestDTO;
import com.demo.service.impl.AdvancedScheduleServiceImpl;
import com.demo.service.impl.GeneticScheduleServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 排课管理控制器
 */
@RestController
@RequestMapping("/schedule")
@CrossOrigin
public class ScheduleController {
    
    @Autowired
    private ScheduleService scheduleService;
    
    @Autowired
    private IntelligentScheduleService intelligentScheduleService;
    
    @Autowired(required = false)
    private AdvancedScheduleServiceImpl advancedScheduleService;
    
    @Autowired(required = false)
    private GeneticScheduleServiceImpl geneticScheduleService;
    
    /**
     * 获取排课列表
     */
    @GetMapping("/list")
    public Result<List<ScheduleListDTO>> getScheduleList() {
        try {
            List<ScheduleListDTO> list = scheduleService.getScheduleList();
            return Result.success(list);
        } catch (Exception e) {
            return Result.error("获取排课列表失败：" + e.getMessage());
        }
    }

    /**
     * 分页获取排课列表
     */
    @GetMapping("/page")
    public Result<Object> getSchedulePage(@RequestParam(defaultValue = "1") int page,
                                          @RequestParam(defaultValue = "10") int pageSize) {
        try {
            return Result.success(scheduleService.getSchedulePage(page, pageSize));
        } catch (Exception e) {
            return Result.error("分页获取排课列表失败：" + e.getMessage());
        }
    }
    
    /**
     * 智能排课
     */
    @PostMapping("/intelligent/{semester}")
    public Result<String> intelligentSchedule(@PathVariable String semester) {
        try {
            boolean success = intelligentScheduleService.executeIntelligentSchedule(semester);
            if (success) {
                return Result.success("智能排课成功");
            } else {
                return Result.error("智能排课失败");
            }
        } catch (Exception e) {
            return Result.error("智能排课失败：" + e.getMessage());
        }
    }
    
    /**
     * 高级智能排课（支持选择班级/课程、课时限制、均衡分配与冲突规避）
     */
    @PostMapping("/intelligent-advanced")
    public Result<String> intelligentAdvanced(@RequestBody AdvancedScheduleRequestDTO request) {
        try {
            if (advancedScheduleService == null) {
                return Result.error("高级排课服务未启用");
            }
            boolean success = advancedScheduleService.executeAdvancedSchedule(request);
            return success ? Result.success("高级智能排课成功") : Result.error("高级智能排课失败");
        } catch (Exception e) {
            return Result.error("高级智能排课失败：" + e.getMessage());
        }
    }

    /**
     * 遗传算法排课（支持与高级请求相同的参数体）
     */
    @PostMapping("/intelligent-ga")
    public Result<String> intelligentGenetic(@RequestBody AdvancedScheduleRequestDTO request) {
        try {
            if (geneticScheduleService == null) {
                return Result.error("遗传算法服务未启用");
            }
            boolean success = geneticScheduleService.executeAdvancedSchedule(request);
            return success ? Result.success("遗传算法排课成功") : Result.error("遗传算法排课失败");
        } catch (Exception e) {
            return Result.error("遗传算法排课失败：" + e.getMessage());
        }
    }
    
    /**
     * 添加排课
     */
    @PostMapping("/add")
    public Result<String> addSchedule(@RequestBody Schedule schedule) {
        try {
            // 如果前端传递了时间信息但没有 time_slot_id，需要查找对应的 time_slot_id
            if (schedule.getTimeSlotId() == null) {
                Long timeSlotId = scheduleService.findTimeSlotId(schedule);
                if (timeSlotId == null) {
                    return Result.error("未找到对应的时间段，请检查周次、星期、节次信息");
                }
                schedule.setTimeSlotId(timeSlotId);
            }
            
            if (scheduleService.checkScheduleConflict(schedule)) {
                scheduleService.save(schedule);
                return Result.success("添加排课成功");
            } else {
                return Result.error("排课存在冲突，请检查时间安排");
            }
        } catch (Exception e) {
            return Result.error("添加排课失败：" + e.getMessage());
        }
    }
    
    /**
     * 更新排课
     */
    @PutMapping("/update")
    public Result<String> updateSchedule(@RequestBody Schedule schedule) {
        try {
            if (scheduleService.checkScheduleConflict(schedule)) {
                scheduleService.updateById(schedule);
                return Result.success("更新排课成功");
            } else {
                return Result.error("排课存在冲突，请检查时间安排");
            }
        } catch (Exception e) {
            return Result.error("更新排课失败：" + e.getMessage());
        }
    }
    
    /**
     * 删除排课
     */
    @DeleteMapping("/delete/{id}")
    public Result<String> deleteSchedule(@PathVariable Long id) {
        try {
            scheduleService.removeById(id);
            return Result.success("删除排课成功");
        } catch (Exception e) {
            return Result.error("删除排课失败：" + e.getMessage());
        }
    }
    
    /**
     * 获取教师课表
     */
    @GetMapping("/teacher/{teacherId}/{semester}")
    public Result<List<ScheduleListDTO>> getTeacherSchedule(@PathVariable Long teacherId, 
                                                          @PathVariable String semester) {
        try {
            List<ScheduleListDTO> list = scheduleService.getTeacherSchedule(teacherId, semester);
            return Result.success(list);
        } catch (Exception e) {
            return Result.error("获取教师课表失败：" + e.getMessage());
        }
    }
    
    /**
     * 获取班级课表
     */
    @GetMapping("/class/{clazzId}/{semester}")
    public Result<List<ScheduleListDTO>> getClassSchedule(@PathVariable Long clazzId, 
                                                         @PathVariable String semester) {
        try {
            List<ScheduleListDTO> list = scheduleService.getClassSchedule(clazzId, semester);
            return Result.success(list);
        } catch (Exception e) {
            return Result.error("获取班级课表失败：" + e.getMessage());
        }
    }
    
    /**
     * 获取教室课表
     */
    @GetMapping("/classroom/{classroomId}/{semester}")
    public Result<List<ScheduleListDTO>> getClassroomSchedule(@PathVariable Long classroomId, 
                                                            @PathVariable String semester) {
        try {
            List<ScheduleListDTO> list = scheduleService.getClassroomSchedule(classroomId, semester);
            return Result.success(list);
        } catch (Exception e) {
            return Result.error("获取教室课表失败：" + e.getMessage());
        }
    }
    
    /**
     * 检查排课冲突
     */
    @PostMapping("/check-conflict")
    public Result<Boolean> checkScheduleConflict(@RequestBody Schedule schedule) {
        try {
            boolean hasConflict = !scheduleService.checkScheduleConflict(schedule);
            return Result.success(hasConflict);
        } catch (Exception e) {
            return Result.error("检查排课冲突失败：" + e.getMessage());
        }
    }
    
    /**
     * 检查某班级在指定学期的周课时总量（用于前端快速校验每周≤N节）
     */
    @GetMapping("/check-weekly-limit/{clazzId}")
    public Result<Integer> checkWeeklyLimit(@PathVariable Long clazzId, @RequestParam(required = false) String semester) {
        try {
            // 学期兜底：优先使用传入；否则优先 advanced，其次 2025-1
            String useSemester = semester;
            if (useSemester == null || useSemester.isEmpty()) {
                // 检查 advanced 是否存在
                Long cntAdvanced = scheduleService.count(new QueryWrapper<Schedule>()
                        .eq("clazz_id", clazzId)
                        .inSql("time_slot_id", "select time_slot_id from time_slot where semester = 'advanced'"));
                if (cntAdvanced != null && cntAdvanced > 0) {
                    useSemester = "advanced";
                } else {
                    useSemester = "2025-1";
                }
            }

            QueryWrapper<Schedule> qw = new QueryWrapper<>();
            qw.eq("clazz_id", clazzId)
              .inSql("time_slot_id", "select time_slot_id from time_slot where semester = '" + useSemester + "'");
            long count = scheduleService.count(qw);
            int weeklyCount = (count > Integer.MAX_VALUE) ? Integer.MAX_VALUE : (int) count;
            return Result.success(weeklyCount);
        } catch (Exception e) {
            // 不抛 500，返回友好错误
            return Result.error("检查每周课时失败，请传入合法学期参数 semester。例如：2025-1 或 advanced");
        }
    }
}


